<?php
/**
 * Created by PhpStorm.
 * User: Keter
 * Date: 2016/8/12
 * Time: 18:00
 */
class MysqlDriver extends Base
{
    private $_instance;
    private $_stmt;

    public $host;
    public $port;
    public $user;
    public $name;

    /**
     * 连接数据库
     * @param $config
     * @return bool
     */
    public function connect($config)
    {
        extract($config);
        $timeout = isset($timeout) ? $timeout : 0;
        $port = isset($port) ? $port : 3306;
        $charset = isset($charset) ? $charset : 'UTF8';

        $this->_instance = new mysqli();
        $this->_instance->options(MYSQLI_OPT_CONNECT_TIMEOUT, $timeout);

        $connect = @$this->_instance->real_connect(
            $host, $user, $password, $dbName, $port
        );

        if (!$connect) {
            return false;
        }

        $this->host = $host;
        $this->port = $port;
        $this->user = $user;
        $this->name = $dbName;

        $this->_stmt = $this->_instance->stmt_init();
        $this->set_charset($charset);
        return true;
    }

    /**
     * 选择数据库
     * @param string $name
     */
    public function select_db($name)
    {
        $result = $this->_instance->select_db($name);
        if ($result) {
            $this->name = $name;
        }

        return $result;
    }

    /**
     * 查询
     * @param $sql
     * @param int $resultmode
     * @return mixed
     */
    public function query($sql, $resultmode = MYSQLI_STORE_RESULT)
    {
        $this->_recordSet = $this->_instance->query($sql);
        return $this->_recordSet;
    }

    /**
     * 关闭
     */
    public function close()
    {
        @$this->_stmt->close();
        $this->_instance->close();
    }

    /**
     * 取一行值
     */
    public function fetch_num()
    {
        $result = $this->_recordSet->fetch_array(MYSQLI_NUM);
        return $result ? $result : array();
    }

    /**
     * 取一行数组结果
     */
    public function fetch_array()
    {
        $result = $this->_recordSet->fetch_array(MYSQLI_ASSOC);
        return $result ? $result : array();
    }

    /**
     * 取一条Object结果
     */
    public function fetch_object()
    {
        $result = $this->_recordSet->fetch_object();
        return $result ? $result : array();
    }

    public function fetch_assoc()
    {
        $result = $this->_recordSet->fetch_assoc();
        return $result ? $result : array();
    }

    /**
     * 取所有记录
     */
    public function fetch_all($resultmode = MYSQLI_ASSOC)
    {
        $result = array();

        if (method_exists($this->_recordSet, 'fetch_all')) {
            $result = $this->_recordSet->fetch_all($resultmode);
        } else {
            while ($row = $this->fetch_assoc()) {
                $result[] = $row;
            }
        }

        return $result ? $result : array();
    }

    /**
     * 取一行
     */
    public function fetch_row()
    {
        $result = $this->_recordSet->fetch_row();
        return $result ? $result : array();
    }

    /**
     * 释放结果集
     */
    public function free_result()
    {
        $this->_stmt->free_result();
        $this->_recordSet = null;
    }

    /**
     * 获取总数
     * @return mixed
     */
    public function num_rows()
    {
        return $this->_recordSet->num_rows;
    }

    /**
     * 跳转指针
     * @param int $num
     * @return mixed
     */
    public function data_seek($num = 0)
    {
        return $this->_recordSet->data_seek($num);
    }

    /**
     * 获取影响的行数
     * @return mixed
     */
    public function affected_rows()
    {
        return $this->_instance->affected_rows;
    }

    /**
     * 获取错误号
     * @return mixed
     */
    public function error_no()
    {
        return $this->_instance->errno;
    }

    /**
     * 获取错误消息
     * @return mixed
     */
    public function error()
    {
        return $this->_instance->error;
    }

    /**
     * 获取错误列表
     * @return mixed
     */
    public function error_list()
    {
        return $this->_instance->error_list;
    }

    /**
     * 字段安全注入防范
     * @param $str
     * @return mixed
     */
    public function real_escape_string($str)
    {
        return $this->_instance->real_escape_string($str);
    }

    /**
     * 设置字符集
     * @param $charset
     * @return mixed
     */
    public function set_charset($charset)
    {
        return $this->_instance->set_charset($charset);
    }

    /**
     * 显示字段
     * @param $sql
     * @return mixed
     */
    public function show_fields($sql)
    {
        return $this->_instance->query($sql);
    }

    /**
     * 预处理
     * @param $sql
     * @return mixed
     */
    public function prepare($sql)
    {
        $result = $this->_stmt->prepare($sql);
        return $result;
    }

    /**
     * 绑定参数
     * @param string $parameter
     * @param mixed $variable
     */
    public function bind_param($parameter, &$variable)
    {
        $result = call_user_func_array(array($this->_stmt, 'bind_param'), func_get_args());
        return $result;
    }

    /**
     * 绑定参数
     * @param mixed $vars
     */
    public function bind_result(&$vars)
    {
        $result = call_user_func_array(array($this->_stmt, 'bind_result'), func_get_args());
        return $result;
    }

    /**
     * 执行SQL
     */
    public function execute()
    {
        $result = $this->_stmt->execute();
        $this->_recordSet = $this->_stmt->get_result();
        $this->_stmt->free_result();
        return $result;
    }

    /**
     * 探测Mysql是否连接超时
     * @return mixed
     */
    public function ping()
    {
        return @$this->_instance->ping();
    }

    /**
     * 未知方法调用的处理
     * @param string $name
     * @param array $params
     */
    public function __call($name, $params)
    {
        if ($this->_instance && method_exists($this->_instance, $name)) {
            return call_user_func_array(array($this->_instance, $name), $params);
        }
    }
}